package hardware

import (
	"fmt"
	"os/exec"
	"runtime"
	"strings"
	"time"
)

// HardwareInfo 硬件信息结构
type HardwareInfo struct {
	CPUID      string
	CPUName    string
	MacAddress string
	Timestamp  time.Time
}

// GetHardwareInfo 获取硬件信息
func GetHardwareInfo() (*HardwareInfo, error) {
	info := &HardwareInfo{
		Timestamp: time.Now(),
	}

	platform := runtime.GOOS

	switch platform {
	case "windows":
		return getWindowsHardwareInfo(info)
	case "linux":
		return getLinuxHardwareInfo(info)
	case "darwin":
		return getDarwinHardwareInfo(info)
	default:
		return nil, fmt.Errorf("不支持的平台: %s", platform)
	}
}

// getWindowsHardwareInfo 获取Windows系统硬件信息
func getWindowsHardwareInfo(info *HardwareInfo) (*HardwareInfo, error) {
    var out []byte
    var err error

    // 1. 获取 CPU ID
    out, err = exec.Command("powershell", "-NoProfile", "-Command",
        "(Get-WmiObject win32_processor).ProcessorId").Output()
    if err != nil {
        info.CPUID = "N/A"
    } else {
        info.CPUID = strings.TrimSpace(string(out))
    }

    // 2. 获取 CPU 名称
    out, err = exec.Command("powershell", "-NoProfile", "-Command",
        "(Get-WmiObject win32_processor).Name").Output()
    if err != nil {
        info.CPUName = "N/A"
    } else {
        info.CPUName = strings.TrimSpace(string(out))
    }

    // 3. 获取 MAC 地址
    out, err = exec.Command("powershell", "-NoProfile", "-Command",
        "((Get-CimInstance win32_networkadapter | Where-Object {$_.NetEnabled}).MACAddress | Select-Object -First 1)").Output()
    if err != nil {
        info.MacAddress = "N/A"
    } else {
        info.MacAddress = strings.ToLower(strings.TrimSpace(string(out)))
    }

    return info, nil
}

// getLinuxHardwareInfo 获取Linux系统硬件信息
func getLinuxHardwareInfo(info *HardwareInfo) (*HardwareInfo, error) {
	// 获取CPU ID
	cpuIDOut, err := exec.Command("sh", "-c", `dmidecode -t processor | grep "ID:" | head -n1`).Output()
	if err != nil {
		info.CPUID = "N/A"
	} else {
		info.CPUID = strings.TrimSpace(strings.ReplaceAll(string(cpuIDOut), "ID:", ""))
	}

	// 获取CPU名称
	cpuNameOut, err := exec.Command("sh", "-c", `cat /proc/cpuinfo | grep -m1 'model name' | sed 's/.*:\s*//'`).Output()
	if err != nil {
		info.CPUName = "N/A"
	} else {
		info.CPUName = strings.TrimSpace(string(cpuNameOut))
	}

	// 获取MAC地址
	macOut, err := exec.Command("sh", "-c", "cat /sys/class/net/eth0/address").Output()
	if err != nil {
		info.MacAddress = "N/A"
	} else {
		info.MacAddress = strings.TrimSpace(string(macOut))
	}

	return info, nil
}

// getDarwinHardwareInfo 获取macOS系统硬件信息
func getDarwinHardwareInfo(info *HardwareInfo) (*HardwareInfo, error) {
	// 获取CPU信息
	cpuOut, err := exec.Command("sysctl", "-n", "machdep.cpu.brand_string").Output()
	if err != nil {
		info.CPUID = "N/A"
		info.CPUName = "N/A"
	} else {
		cpuInfo := strings.TrimSpace(string(cpuOut))
		info.CPUID = strings.ReplaceAll(cpuInfo, " ", "-")
		info.CPUName = cpuInfo
	}

	// 获取MAC地址
	macOut, err := exec.Command("sh", "-c", "networksetup -listallhardwareports | awk '/Ethernet Address/{print $3}' | head -n 1").Output()
	if err != nil {
		info.MacAddress = "N/A"
	} else {
		info.MacAddress = strings.ToLower(strings.TrimSpace(string(macOut)))
	}

	return info, nil
}